package com.atguigu.srb.core.config;


import com.atguigu.srb.core.pojo.entity.User;
import com.atguigu.srb.core.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;

import javax.annotation.Resource;

/**
 * 实现用户登录认证逻辑
 */
public class UserRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;

    /**
     * 用户授权的逻辑代码
     */
    // 覆盖（Override）父类中的doGetAuthorizationInfo方法，用于执行用户授权逻辑
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了===>用户授权"); // 打印日志，表示执行了授权逻辑
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // 创建一个用于存储授权信息的SimpleAuthorizationInfo对象

        // 获取当前登录的用户对象
        Subject subject = SecurityUtils.getSubject();
        // 从Subject对象中获取用户信息，这里假设用户信息是以User对象的形式存储的
        User currentUser = (User) subject.getPrincipal();

        // 将当前用户的权限添加到授权信息对象中，这里假设User对象有一个getPermissions方法返回权限字符串
        info.addStringPermission(currentUser.getPermissions());

        // 返回填充了权限信息的授权信息对象
        return info;
    }

    /**
     * 用户认证的逻辑代码
     */
// 覆盖（Override）父类中的doGetAuthenticationInfo方法，用于执行用户认证逻辑
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了===>用户认证"); // 打印日志，表示执行了认证逻辑

        // 将传入的AuthenticationToken对象转换为UsernamePasswordToken对象，这是Shiro用于用户名和密码认证的特定Token类型
        UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
        User user = new User();

        // 通过userService调用数据层的方法，根据用户名查询用户信息，这里假设userService是已经注入的服务层对象
        user = userService.findUserByName(token.getUsername());


        // 如果查询到的用户为null，即数据库中不存在该用户，则认证失败，返回null
        if(user == null){
            return null;
        }


        // 获取当前的Subject对象，Subject是Shiro的核心概念，代表了当前“用户”
        Subject subject = SecurityUtils.getSubject();

        // 将登录成功的用户信息放入Session中，以便在其他地方可以获取当前登录的用户信息
        subject.getSession().setAttribute("loginUser", user);

        // 创建并返回一个SimpleAuthenticationInfo对象，包含用户的基本信息，用于密码认证
        // 第三个参数是realm名称，这里留空
        return new SimpleAuthenticationInfo(user, user.getPassword(), "");
    }
}